import _ from 'underscore';
import BaseFormWidget from './BaseFormWidget.js';
import {
    getOpt
} from "../tools.js";
import {
    updateSelectOptions
} from '../tools.js';

var template = require('./templates/SelectWidget.mustache');

/**
 * A select widget
 *
 * Features :
 *  - single or multiple item selector
 *  - optionaly supports empty value
 *
 * Triggers :
 *
 * On Value selection
 *
 * @fires finishEventName - named finish by default, current value passed as param
 * @fires finishEventName:field_name - named "finish":field_name by default,
 * current value passed as param
 *
 *
 *
 * See BaseFormWidget for main options
 *
 * SelectWidget specific options :
 *
 *   @param {list} options: The options to render in the form [{id_key: 21, label_key: "Option 21"}]
 *   @param {string} value: The value to select
 *   @param {string} id_key: The key of the options used as option's "value", default is "value"
 *   @param {string} label_key: The key of the options used as label default is label
 *   @param {string} placeholder: placeholder text, will add an <option> with
 *     value="" ; can be set to empty string for empty label <option>
 *     as placeholder.
 *   @param {boolean} multiple: does this widget allow selecting multiple targets
 */
const SelectWidget = BaseFormWidget.extend({
    tagName: 'div',
    className: 'form-group',
    template: template,
    ui: {
        select: 'select'
    },
    events: {
        'change @ui.select': "onChange"
    },
    initialize() {
        SelectWidget.__super__.initialize.apply(this, arguments);
        this.id_key = getOpt(this, 'id_key', 'value');
        this.label_key = getOpt(this, 'label_key', 'label');
    },
    onChange: function (event) {
        const select = this.getUI('select');
        const field_values = this.getCurrentValues();
        this.options.value = field_values;

        // Fix #3350 : select pas multiple renvoie une seule valeur
        if (getOpt(this, 'multiple', false)) {
            this.triggerFinish(field_values);
        } else {
            const value = select.val();
            this.triggerFinish(value);
        }

        // specific to select
        this.triggerMethod(
            'labelChange',
            this.getOption('field_name'),
            select.find('option:selected').text(),
        );
    },
    /** Return currently selected values
     *
     * this.getOption('value') is not always relevant as it contains only the
     * initial value (from widget initialization).
     */
    getCurrentValues: function () {
        let optionNodes = $.makeArray(this.$el.find('option:selected'));
        return optionNodes.map((x) => x.getAttribute('value'));
    },
    initializePlaceHolder: function (placeholder, options) {
        let placeholderOption = {
            [this.id_key]: '',
            [this.label_key]: placeholder,
        };
        if ((!_.findWhere(options, placeholderOption))) {
            options.unshift(placeholderOption);
        }
    },
    templateContext: function () {
        let ctx = this.getCommonContext();

        // If some ad-hoc filtering of displayed options is required, read
        // CheckBoxListWidget implementation for inspiration.

        // do not use getOption as there is name collision on "options"
        var options = this.options.options || [];

        var initialValue = this.getOption('value');

        let hasInitialValue = !_.isUndefined(initialValue) && !_.isNull(initialValue);
        if (hasInitialValue) {
            updateSelectOptions(options, initialValue, this.id_key);
        }

        let placeholder = getOpt(this, 'placeholder', undefined);
        let hasPlaceHolder = !_.isUndefined(placeholder);
        if (hasPlaceHolder) {
            this.initializePlaceHolder(placeholder, options);
        }
        let multiple = getOpt(this, 'multiple', false);
        let more_ctx = {
            options: options,
            id_key: this.id_key,
            label_key: this.label_key,
            multiple: multiple,
        };
        return Object.assign(ctx, more_ctx);
    },
});
export default SelectWidget;
